home *** CD-ROM | disk | FTP | other *** search
/ Nejlepší hry / Nejlepsi hry.iso / hry / plane arcade / planearcade.exe / tank3.bmp / octree.cpp < prev    next >
C/C++ Source or Header  |  2004-09-28  |  38KB  |  1,709 lines

  1.  
  2. #include "main.h"
  3.  
  4.  
  5.  
  6. //------------------------------------------------------------------
  7. // Name: OCTREE()
  8. // Desc: konstruktor
  9. //------------------------------------------------------------------
  10. OCTREE::OCTREE()
  11. {
  12.     g_pVB = NULL;
  13.     Group = NULL;
  14.     Face = NULL;
  15.     Node = NULL;
  16.     FileScn = NULL;
  17.     FileGeo = NULL;
  18.     FileOct = NULL;
  19. }
  20.  
  21. //------------------------------------------------------------------
  22. // Name: CleanUp()
  23. // Desc: Odstrani
  24. //------------------------------------------------------------------
  25. void OCTREE::CleanUp()
  26. {
  27.     
  28.     //
  29.     //vertex buffer
  30.     //
  31.     if (g_pVB != NULL)
  32.         g_pVB->Release();
  33.     g_pVB = NULL;
  34.  
  35.     //
  36.     //skupina
  37.     //
  38.     if (Group != NULL)
  39.     {
  40.         //znic textury
  41.         for (int i=0;i<NumGroups;i++)
  42.         {
  43.             ClearGroupTextures(i);
  44.         }
  45.  
  46.         delete [] Group;
  47.     }
  48.     Group = NULL;
  49.  
  50.     //
  51.     //face
  52.     //
  53.     if (Face != NULL)
  54.         delete [] Face;
  55.     Face = NULL;
  56.  
  57.     //
  58.     //Octree
  59.     //
  60.     if (Node != NULL)
  61.         delete [] Node;
  62.  
  63.     //
  64.     //kolizia
  65.     //
  66.     IntPos = Get3D(0,0,0);
  67.     IntNormal = Get3D(0,0,0);
  68.     ColliseStatus = false;
  69.  
  70. }
  71.  
  72. //------------------------------------------------------------------
  73. // Name: InitializeGroup()
  74. // Desc: inicializuje textury group
  75. //------------------------------------------------------------------
  76. void OCTREE::InitializeGroupTextures(int Index)
  77. {
  78.  
  79.     int NumTextures = Group[Index].NumTextures;
  80.  
  81.     Group[Index].g_pTexture = new LPDIRECT3DTEXTURE9[NumTextures];
  82.     
  83.     for (int i=0;i<NumTextures;i++)
  84.     {
  85.         Group[Index].g_pTexture[i] = NULL;
  86.     }
  87. }
  88.  
  89.  
  90. //------------------------------------------------------------------
  91. // Name: ClearGroup()
  92. // Desc: Odtrani z pamati textury group
  93. //------------------------------------------------------------------
  94. void OCTREE::ClearGroupTextures(int Index)
  95. {
  96.     
  97.     if(Group[Index].g_pTexture != NULL)
  98.     {
  99.         for (int i=0;i<Group[Index].NumTextures;i++)
  100.         {
  101.             if (Group[Index].g_pTexture[i] != NULL)
  102.                 Group[Index].g_pTexture[i]->Release();
  103.             Group[Index].g_pTexture[i] = NULL;
  104.         }
  105.     }
  106.     
  107.     delete [] Group[Index].g_pTexture;
  108.     Group[Index].g_pTexture = NULL;
  109.  
  110. }
  111.  
  112. //------------------------------------------------------------------
  113. // Name: Load()
  114. // Desc: nahra scenu zo suboru GEO
  115. //------------------------------------------------------------------
  116. void OCTREE::Load(char *FileName)
  117. {
  118.  
  119.     char cBuf[80];
  120.     int i;
  121.  
  122.  
  123.     //Log
  124.     LogPrint("Vytvaram OCTree");
  125.     sprintf(cBuf," Subor: %s",FileName);
  126.     LogPrint(cBuf);
  127.     
  128.  
  129.     ///////////////
  130.     //otvor subor//
  131.     ///////////////
  132.     FileGeo = fopen(FileName,"r");
  133.  
  134.     if (FileGeo == NULL)
  135.         LogPrint(" Subor sa nepodarilo otvrit");
  136.  
  137.  
  138.     ///////////////
  139.     //hlavicka   //
  140.     ///////////////
  141.     fscanf(FileGeo,"%s %d",cBuf,&MinNodeSize);
  142.     fscanf(FileGeo,"%s %d",cBuf,&NumGroups);
  143.     fscanf(FileGeo,"%s %d",cBuf,&NumFaces);
  144.  
  145.     sprintf(cBuf," MinPolygonsInNode: %d",MinNodeSize);
  146.     LogPrint(cBuf);
  147.     sprintf(cBuf," NumGroups: %d",NumGroups);
  148.     LogPrint(cBuf);
  149.     sprintf(cBuf," NumFaces: %d",NumFaces);
  150.     LogPrint(cBuf);
  151.     
  152.  
  153.     ///////////////
  154.     //group      //
  155.     ///////////////
  156.     Group = new OCTGROUP[NumGroups];
  157.     for (i=0;i<NumGroups;i++)
  158.     {
  159.         ReadGroup();
  160.     }
  161.  
  162.     ///////////////
  163.     //faces      //
  164.     ///////////////
  165.     Face = new OCTFACE[NumFaces];
  166.     for (i=0;i<NumFaces;i++)
  167.     {
  168.         ReadFace();
  169.     }
  170.  
  171.     /////////////////
  172.     //Vertex Buffer//
  173.     /////////////////
  174.     CreateVertexBuffer();
  175.  
  176.  
  177.     /////////////////
  178.     //SmoothShading//
  179.     /////////////////
  180.     for (i=0;i<NumGroups;i++)
  181.     {
  182.         if (Group[i].SmoothShading == 1)
  183.         {
  184.             CalcSmoothShading(i);
  185.         }
  186.     }
  187.  
  188.     ///////////
  189.     //OCTree //
  190.     ///////////
  191.     //CreateOctTree();
  192.     //SaveOctTree("scene/terrain.oct");
  193.     //LoadOctTree("scene/terrain.oct");
  194.  
  195.     ////////////////
  196.     //zatvor subor//
  197.     ////////////////
  198.     fclose(FileGeo);
  199.  
  200. }
  201.  
  202.  
  203. //------------------------------------------------------------------
  204. // Name: ReadGroup()
  205. // Desc: Precita a nahraje group
  206. //------------------------------------------------------------------
  207. void OCTREE::ReadGroup()
  208. {
  209.  
  210.     char cBuf[80];
  211.     char TexFileName[80];
  212.     int Index;
  213.     int TexIndex;
  214.  
  215.     fscanf(FileGeo,"%s",cBuf);
  216.     
  217.     fscanf(FileGeo,"%s %d",cBuf,&Index);
  218.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].NumTextures);
  219.     fscanf(FileGeo,"%s %f",cBuf,&Group[Index].TextureTime);
  220.  
  221.     //log
  222.     sprintf(cBuf," Material %d",Index);
  223.     LogPrint(cBuf);
  224.  
  225.     //default vlastnosti
  226.     Group[Index].ActTexture = 0;
  227.     Group[Index].ActTime = 0.0f;
  228.  
  229.     //inicializacia pola textur
  230.     InitializeGroupTextures(Index);
  231.  
  232.     ///////////////////
  233.     //Nahraje textury//
  234.     ///////////////////
  235.     for (int i=0;i<Group[Index].NumTextures;i++)
  236.     {
  237.         
  238.         fscanf(FileGeo,"%s %d %s",cBuf,&TexIndex,TexFileName);
  239.  
  240.         sprintf(cBuf,"  Textura %s",TexFileName);
  241.         LogPrint(cBuf);
  242.     
  243.         //load hlavnej terrain textury
  244.         if (Index == 0 && (i == 0 || i == 2))
  245.         {
  246.             int TextureSize;
  247.             if (SceneDetail == 0) TextureSize = 512;
  248.             if (SceneDetail == 1) TextureSize = 1024;
  249.             if (SceneDetail == 2) TextureSize = 2048;
  250.             
  251.             if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, 
  252.                                       TexFileName,    
  253.                                       TextureSize, 
  254.                                       TextureSize, 
  255.                                       0,              //MipLevels
  256.                                       0,            
  257.                                       D3DFMT_R5G6B5, 
  258.                                       D3DPOOL_DEFAULT,
  259.                                       D3DX_DEFAULT, //Filter
  260.                                       D3DX_DEFAULT, //MipFilter
  261.                                       0,    //Disable ColorKey
  262.                                       NULL,         
  263.                                       NULL,         
  264.                                       &Group[Index].g_pTexture[i])))  
  265.             {
  266.                 sprintf(cBuf,"  chyba pri vytvarani textury: %s",TexFileName);
  267.                 LogPrint(cBuf);
  268.             }
  269.  
  270.         }
  271.  
  272.         //load ostatnych textur
  273.         else
  274.         {
  275.             if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, 
  276.                                       TexFileName,    
  277.                                       D3DX_DEFAULT, 
  278.                                       D3DX_DEFAULT, 
  279.                                       Engine.MipMapLevels,   //MipLevels
  280.                                       0,            
  281.                                       Engine.TextureFormat, 
  282.                                       D3DPOOL_DEFAULT,
  283.                                       D3DX_DEFAULT, //Filter
  284.                                       D3DX_DEFAULT, //MipFilter
  285.                                       0xffff00ff,    //ColorKey
  286.                                       NULL,         
  287.                                       NULL,         
  288.                                       &Group[Index].g_pTexture[i])))  
  289.             {
  290.                 sprintf(cBuf,"  chyba pri vytvarani textury: %s",TexFileName);
  291.                 LogPrint(cBuf);
  292.             }
  293.         }
  294.     
  295.  
  296.     }
  297.  
  298.     //nacitaj dalsie vlastnosti
  299.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].BlendType );
  300.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].GroupType );
  301.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].MaterialType  );
  302.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].CollisionType );
  303.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].Specular );
  304.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].SmoothShading );
  305.  
  306. }
  307.  
  308.  
  309.  
  310. //------------------------------------------------------------------
  311. // Name: ReadFace()
  312. // Desc: Precita a nahraje face
  313. //------------------------------------------------------------------
  314. void OCTREE::ReadFace()
  315. {
  316.     char cBuf[80];
  317.     int Index;
  318.     int GroupIndex;
  319.     float X,Y,Z,U,V;
  320.  
  321.     fscanf(FileGeo,"%s",cBuf);
  322.  
  323.     //nacitaj hlavicku
  324.     fscanf(FileGeo,"%s %d",cBuf,&Index);
  325.     fscanf(FileGeo,"%s %d",cBuf,&GroupIndex);
  326.  
  327.     //nacitaj body
  328.     for(int i=2;i>-1;i--)
  329.     {
  330.         fscanf(FileGeo,"%f %f %f %f %f",&X,&Y,&Z,&U,&V);
  331.         
  332.         Face[Index].P[i] = Get3D(X,Y,Z);
  333.         Face[Index].T1[i].X = U;
  334.         Face[Index].T1[i].Y = V;
  335.  
  336.     }
  337.  
  338.     //plane
  339.     Face[Index].Plane = CreatePlaneFace(Face[Index].P[0],
  340.                                         Face[Index].P[1],
  341.                                         Face[Index].P[2]);
  342.  
  343.     //normaly
  344.     Face[Index].N[0] = Face[Index].Plane.Normal ;
  345.     Face[Index].N[1] = Face[Index].Plane.Normal ;
  346.     Face[Index].N[2] = Face[Index].Plane.Normal ;
  347.  
  348.     //texcoord2
  349.     Face[Index].T2[0].X = Face[Index].P[0].X / 500.0f;
  350.     Face[Index].T2[0].Y = Face[Index].P[0].Z / 500.0f;
  351.  
  352.     Face[Index].T2[1].X = Face[Index].P[1].X / 500.0f;
  353.     Face[Index].T2[1].Y = Face[Index].P[1].Z / 500.0f;
  354.  
  355.     Face[Index].T2[2].X = Face[Index].P[2].X / 500.0f;
  356.     Face[Index].T2[2].Y = Face[Index].P[2].Z / 500.0f;
  357.  
  358.     //vlastnosti
  359.     Face[Index].Group = GroupIndex;
  360.     Face[Index].Index = Index;
  361.     
  362.  
  363. }
  364.  
  365. //------------------------------------------------------------------
  366. // Name: CreateVertexBuffer()
  367. // Desc: Vytvori Vertex Buffer
  368. //------------------------------------------------------------------
  369. void OCTREE::CreateVertexBuffer()
  370. {
  371.  
  372.     if (FAILED(g_pd3dDevice->CreateVertexBuffer(NumFaces*3*sizeof(CUSTOMVERTEXOCT),
  373.                                    D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, D3DFVF_CUSTOMVERTEXOCT,
  374.                                    D3DPOOL_DEFAULT, &g_pVB, NULL )))
  375.       {
  376.         LogPrint(" Chyba pri vytvarani VB");
  377.     }
  378.     else
  379.     {
  380.         LogPrint(" Vertex Buffer vytvoreny");
  381.     }
  382. }
  383.  
  384.  
  385. //------------------------------------------------------------------
  386. // Name: FillVertexBuffer()
  387. // Desc: Naplni VB a ulozi hodnoty do Group
  388. //------------------------------------------------------------------
  389. void OCTREE::FillVertexBuffer()
  390. {
  391.  
  392.     //pomocne premenne
  393.     int ActVertex = 0;
  394.     int NumF = 0;
  395.     int i,u,j;
  396.  
  397.     //reset pocitadla
  398.     NumVisibleFaces = 0;
  399.  
  400.     //Vertex do ktoreho sa uklada
  401.     CUSTOMVERTEXOCT *Vertex;
  402.  
  403.     //Otvor VB
  404.     g_pVB->Lock(0, 0, (void**)&Vertex, D3DLOCK_DISCARD|D3DLOCK_NOOVERWRITE) ;
  405.  
  406.     /////////
  407.     //GROUP//
  408.     /////////
  409.     for (i=0;i<NumGroups;i++)
  410.     {
  411.         //nastavi pociatocnu hodnotu
  412.         Group[i].StartVertex = ActVertex;
  413.         NumF = 0;
  414.         
  415.         for (u=0;u<NumFaces;u++)
  416.         {
  417.             if (Face[u].Visible == true)
  418.             {
  419.                 if (Face[u].Group == i)
  420.                 {
  421.                     //pocitadlo
  422.                     NumVisibleFaces++;
  423.                                 
  424.                     for (j=0;j<3;j++)
  425.                     {
  426.                         //prida vertex do VB
  427.                         Vertex[ActVertex].normal = D3DXVECTOR3(Face[u].N[j].X,
  428.                                                                Face[u].N[j].Y,
  429.                                                                Face[u].N[j].Z);
  430.     
  431.                         Vertex[ActVertex].pos  = D3DXVECTOR3(Face[u].P[j].X,
  432.                                                              Face[u].P[j].Y,
  433.                                                              Face[u].P[j].Z);
  434.  
  435.                         Vertex[ActVertex].tu1 = Face[u].T1[j].X;
  436.                         Vertex[ActVertex].tv1 = Face[u].T1[j].Y;
  437.  
  438.                         Vertex[ActVertex].tu2 = Face[u].T2[j].X;
  439.                         Vertex[ActVertex].tv2 = Face[u].T2[j].Y;
  440.  
  441. //
  442. //                        DebugDrawLine(Face[u].P[j],Get3D(Face[u].P[j].X+(2.0f*Face[u].N[j].X),
  443. //                                                         Face[u].P[j].Y+(2.0f*Face[u].N[j].Y),
  444. //                                                         Face[u].P[j].Z+(2.0f*Face[u].N[j].Z)));
  445.  
  446.                         ActVertex++;
  447.                     }
  448.  
  449.                     NumF++;
  450.                 }
  451.                     
  452.             }
  453.  
  454.         }
  455.  
  456.         Group[i].NumVisibleFaces = NumF;
  457.     
  458.         
  459.     }
  460.  
  461.  
  462.  
  463.     //zatvor VB
  464.     g_pVB->Unlock();
  465.  
  466. }
  467.  
  468. //------------------------------------------------------------------
  469. // Name: Render()
  470. // Desc: Vyrenderuje celu scenu
  471. //------------------------------------------------------------------
  472. void OCTREE::Render()
  473. {
  474.     int i;
  475.  
  476.     ///////////////
  477.     //Optimalize //
  478.     ///////////////
  479.     Optimalize();
  480.  
  481.     //vynuluje world maticu
  482.     D3DXMATRIXA16 NullMatrix;        
  483.     D3DXMatrixIdentity(&NullMatrix);
  484.     g_pd3dDevice->SetTransform( D3DTS_WORLD, &NullMatrix);
  485.  
  486.     //naplni Vertex Buffer
  487.     FillVertexBuffer();
  488.  
  489.     //oznaci Vertex Buffer
  490.     g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEXOCT));
  491.     g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEXOCT);
  492.  
  493.     ///////////////
  494.     //Render     //
  495.     ///////////////
  496.     //priesvitne materialy nakoniec
  497.  
  498.     //0
  499.     for (i = 0;i<NumGroups;i++)
  500.     {
  501.         Engine.SetLighting(false);
  502.     
  503.         if (Group[i].GroupType == 2 && SceneDetail == 2)
  504.             Engine.SetMipMapping(0,false);
  505.  
  506.         if (Group[i].BlendType == 0)
  507.             RenderGroup(i);
  508.  
  509.         Engine.SetMipMapping(0,true);
  510.     }
  511.  
  512.     //1
  513.     for (i = 0;i<NumGroups;i++)
  514.     {
  515.         Engine.SetAlphaTest(true);
  516.         Engine.SetLighting(false);
  517.         Engine.SetFilter(0,D3DTEXF_NONE);
  518.  
  519.         if (Group[i].BlendType == 1)
  520.             RenderGroup(i);
  521.  
  522.         Engine.SetFilter(0,D3DTEXF_LINEAR);
  523.     }
  524.  
  525.     //2
  526.     for (i = 0;i<NumGroups;i++)
  527.     {
  528.         if (Group[i].BlendType == 2)
  529.             RenderGroup(i);
  530.     }
  531.  
  532.     //zresetuj blending
  533.     Engine.SetBlendNone();
  534.  
  535.     //debug
  536.     //RenderDebugNode(Node);
  537.  
  538.     //reset to default
  539.     Engine.ResetToDefault();
  540. }
  541.  
  542. //------------------------------------------------------------------
  543. // Name: RenderGroup()
  544. // Desc: Vyrenderuje skupinu
  545. //------------------------------------------------------------------
  546. void OCTREE::RenderGroup(int Index)
  547. {
  548.  
  549.     //nastavi material
  550.     SetMaterial(Group[Index].MaterialType );
  551.  
  552.     //nastavi blending
  553.     SetBlendMode(Group[Index].BlendType);
  554.  
  555.     //zapni specular ak je povoleny
  556.     if (Group[Index].Specular == 0)
  557.         Engine.SetSpecular(false);
  558.     else
  559.         Engine.SetSpecular(true);
  560.  
  561.     //ak je iba pre krajinu pole nerenderuj
  562.     if (Group[Index].CollisionType == 1 && Mode == 1)
  563.         return;
  564.  
  565.     //
  566.     //NORMAL TEXTURA
  567.     //
  568.     if(Group[Index].GroupType == 0)
  569.     {
  570.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[0]);
  571.  
  572.     }
  573.  
  574.     //
  575.     //ANIMOVANA TEXTURA
  576.     //
  577.     if(Group[Index].GroupType == 1)
  578.     {
  579.         //vyber textury
  580.         Group[Index].ActTime += PowerTime(1.0f);
  581.         if (Group[Index].ActTime > Group[Index].TextureTime)
  582.         {
  583.             Group[Index].ActTexture++;
  584.             Group[Index].ActTime = 0.0f;    
  585.             if (Group[Index].ActTexture == Group[Index].NumTextures)
  586.                 Group[Index].ActTexture = 0;
  587.         }
  588.         int ActTexture = Group[Index].ActTexture;
  589.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[ActTexture]);
  590.     }
  591.     //
  592.     //MULTITEXTURING
  593.     //
  594.     if(Group[Index].GroupType == 2)
  595.     {
  596.  
  597.         //vyber indexu textury
  598.         int T1,T2;
  599.         if (Mode == 0) { T1 = 0; T2 = 1; }
  600.         if (Mode == 1) { T1 = 2; T2 = 3; }
  601.  
  602.         //1 stage
  603.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[T1]);
  604.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,0);
  605.     
  606.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  607.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  608.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  609.     
  610.         //2 stage
  611.         g_pd3dDevice->SetTexture( 1, Group[Index].g_pTexture[T2]);
  612.         g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX,1);
  613.         g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED);
  614.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  615.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  616.         
  617.     }
  618.     //
  619.     //ENVIROMENT MAPPING
  620.     //
  621.     if(Group[Index].GroupType == 3)
  622.     {
  623.  
  624.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[0]);
  625.  
  626.         for (int i=0;i<NumFaces;i++)
  627.         {
  628.             if (Face[i].Group != Index)
  629.                 continue;
  630.     
  631.             for (int u=0;u<3;u++)
  632.             {
  633.  
  634.                 Face[i].T1[u] = EnvironmentMapping(Face[i].P[u],
  635.                                                    Face[i].N[u],300.0f,matView);
  636.             }
  637.         }
  638.  
  639.  
  640.     }
  641.  
  642.     //
  643.     //EMBOSS BUMB MAPPING
  644.     //
  645.     if(Group[Index].GroupType == 4)
  646.     {
  647.  
  648.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[0] );
  649.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
  650.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  651.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  652.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  653.  
  654.         g_pd3dDevice->SetTexture( 1, Group[Index].g_pTexture[0] );
  655.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
  656.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  657.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  658.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
  659.  
  660.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_ADDSIGNED );
  661.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT );
  662.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
  663.  
  664.         Engine.SetBlendCustom(D3DBLEND_SRCALPHA,D3DBLEND_ZERO);
  665.  
  666.         for (int i=0;i<NumFaces;i++)
  667.         {
  668.             if (Face[i].Group != Index)
  669.                 continue;
  670.     
  671.             for (int u=0;u<3;u++)
  672.             {
  673.                 Face[i].T2[u] = BumpMapping(Face[i].N[u],Face[i].T1[u],0.030f,matView);
  674.             }
  675.         }
  676.  
  677.  
  678.     }
  679.  
  680.     //render
  681.     g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, Group[Index].StartVertex , Group[Index].NumVisibleFaces );
  682.  
  683.     //reset
  684.     Engine.ResetToDefault();
  685. }
  686.  
  687. //------------------------------------------------------------------
  688. // Name: SetMaterial()
  689. // Desc: Nastavi material podla typu
  690. //------------------------------------------------------------------
  691. void OCTREE::SetMaterial(int MaterialType)
  692. {
  693.  
  694.     D3DMATERIAL9 Material;
  695.     ZeroMemory( &Material, sizeof(D3DMATERIAL9) );
  696.  
  697.     switch (MaterialType)
  698.     { 
  699.         case 0: 
  700.             Material = GetMaterial(GetColor(0.2f,0.2f,0.2f,0.2f),
  701.                                    GetColor(1.0f,1.0f,1.0f,1.0f),
  702.                                    GetColor(0.0f,0.0f,0.0f,0.0f),
  703.                                    GetColor(0.0f,0.0f,0.0f,0.0f),0.0f);
  704.  
  705.  
  706.             break;
  707.         case 1: 
  708.             Material = GetMaterial(GetColor(0.3f,0.3f,0.3f,0.3f),
  709.                                    GetColor(1.0f,1.0f,0.0f,0.0f),
  710.                                    GetColor(1.0f,1.0f,1.0f,1.0f),
  711.                                    GetColor(0.2f,0.2f,0.2f,0.2f),5.0f);
  712.  
  713.             break;
  714.         case 2:
  715.  
  716.             break;
  717.     }
  718.         
  719.  
  720.  
  721.     //nastavi material
  722.     g_pd3dDevice->SetMaterial(&Material);
  723.  
  724. }
  725.  
  726. //------------------------------------------------------------------
  727. // Name: SetBlendMode()
  728. // Desc: nastavi priesvitnos¥ podla typu
  729. //------------------------------------------------------------------
  730. void OCTREE::SetBlendMode(int BlendType)
  731. {
  732.     switch (BlendType)
  733.     { 
  734.         case 0: //bez priesvitnosti
  735.             Engine.SetBlendNone();
  736.             break;
  737.         case 1: //transparent
  738.             Engine.SetBlendTrans();
  739.             break;
  740.         case 2: //one
  741.             Engine.SetBlendOne();
  742.             break;
  743.     }
  744. }
  745.  
  746. //------------------------------------------------------------------
  747. // Name: CalcSmoothShading()
  748. // Desc: Vypocita smooth shading pre urcitu skupinu
  749. //------------------------------------------------------------------
  750. void OCTREE::CalcSmoothShading(int Index)
  751. {
  752.     VECTOR3D *Normal = NULL;
  753.     Normal = new VECTOR3D[NumFaces];
  754.     
  755.     for (int i=0;i<NumFaces;i=i+1)
  756.     {
  757.     if (Face[i].Group == Index)
  758.     {
  759.     for (int u=0;u<3;u=u+1)
  760.     {
  761.  
  762.         //bod
  763.         VECTOR3D B = Face[i].P[u];
  764.         
  765.         VECTOR3D NormalVys = Get3D(0.0f,0.0f,0.0f);
  766.         int ActNormal = 0;
  767.  
  768.         //ziskaj normaly
  769.         for (int j=0;j<NumFaces;j=j+1)
  770.         {
  771.         if (Face[i].Group == Index)
  772.         {
  773.         for (int k=0;k<3;k=k+1)
  774.         {
  775.             
  776.  
  777.             if((B.X == Face[j].P[k].X)  &&
  778.                (B.Y == Face[j].P[k].Y)  &&
  779.                (B.Z == Face[j].P[k].Z) )
  780.             {
  781.         
  782.                 Normal[ActNormal] = Face[j].Plane.Normal ;
  783.                 ActNormal++;
  784.                             
  785.             }
  786.  
  787.         }
  788.         }
  789.         }
  790.  
  791.         //vypocitaj normalu
  792.         for (int a=0;a<ActNormal;a++)
  793.         {
  794.             Add(&NormalVys,NormalVys,Normal[a]);
  795.         }
  796.  
  797.         //normalizuj vyslednu normalu
  798.         Normalize(&NormalVys);
  799.  
  800.         //zapis nove normaly
  801.         for (j=0;j<NumFaces;j=j+1)
  802.         {
  803.         if (Face[i].Group == Index)
  804.         {
  805.         for (int k=0;k<3;k=k+1)
  806.         {
  807.  
  808.             if((B.X == Face[j].P[k].X)  &&
  809.                (B.Y == Face[j].P[k].Y)  &&
  810.                (B.Z == Face[j].P[k].Z) )
  811.             {
  812.                 Face[j].N[k] = NormalVys;
  813.             }
  814.  
  815.         }
  816.         }
  817.         }
  818.  
  819.  
  820.     }
  821.     }
  822.     }
  823.  
  824.     if (Normal != NULL)
  825.         delete [] Normal;
  826.     Normal = NULL;
  827. }
  828.  
  829. //------------------------------------------------------------------
  830. // Name: CreateOctTree()
  831. // Desc: vytvori Octree strom
  832. //------------------------------------------------------------------
  833. void OCTREE::CreateOctTree()
  834. {
  835.  
  836.     int i,u;
  837.  
  838.     //log
  839.     LogPrint(" Vytvaram strom");
  840.  
  841.     //vytvori NODE
  842.     Node = new OCTNODE;
  843.  
  844.     ///////////
  845.     //MIN MAX//
  846.     ///////////
  847.     VECTOR3D Min = Get3D(10000.0f,10000.0f,10000.0f);
  848.     VECTOR3D Max = Get3D(-10000.0f,-10000.0f,-10000.0f);
  849.     float a,b,c;
  850.  
  851.     for ( i=0;i<NumFaces;i++)
  852.     {
  853.         for ( u=0;u<3;u++)
  854.         {
  855.             if (Face[i].P[u].X < Min.X)
  856.                 Min.X = Face[i].P[u].X;
  857.             if (Face[i].P[u].Y < Min.Y)
  858.                 Min.Y = Face[i].P[u].Y;
  859.             if (Face[i].P[u].Z < Min.Z)
  860.                 Min.Z = Face[i].P[u].Z;
  861.  
  862.             if (Face[i].P[u].X > Max.X)
  863.                 Max.X = Face[i].P[u].X;
  864.             if (Face[i].P[u].Y > Max.Y)
  865.                 Max.Y = Face[i].P[u].Y;
  866.             if (Face[i].P[u].Z > Max.Z)
  867.                 Max.Z = Face[i].P[u].Z;
  868.         }
  869.     }
  870.  
  871.     
  872.     Node->Centre.X = (Min.X + Max.X) / 2.0f;
  873.     Node->Centre.Y = (Min.Y + Max.Y) / 2.0f;
  874.     Node->Centre.Z = (Min.Z + Max.Z) / 2.0f;
  875.  
  876.     //upravi na kocku
  877.     a = Max.X - Node->Centre.X ;
  878.     b = Max.Y - Node->Centre.Y ;
  879.     c = Max.Z - Node->Centre.Z ;
  880.  
  881.     if (a >= b && a >= c)
  882.     {
  883.         Add(&Node->Max,Node->Centre,Get3D(a,a,a));
  884.         Add(&Node->Min,Node->Centre,Get3D(-a,-a,-a));
  885.     }
  886.     if (b >= a && b >= c)
  887.     {
  888.         Add(&Node->Max,Node->Centre,Get3D(b,b,b));
  889.         Add(&Node->Min,Node->Centre,Get3D(-b,-b,-b));
  890.     }    
  891.     if (c >= b && c >= a)
  892.     {
  893.         Add(&Node->Max,Node->Centre,Get3D(c,c,c));
  894.         Add(&Node->Min,Node->Centre,Get3D(-c,-c,-c));
  895.     }
  896.  
  897.     Node->Polomer = CalcDistance(Node->Centre,Node->Min);
  898.  
  899.     //reset info
  900.     NumEndNodes = 0;
  901.  
  902.     //vytvori octree
  903.     CreateNode(Node);
  904.  
  905.  
  906.  
  907. }
  908.  
  909. //------------------------------------------------------------------
  910. // Name: CreateNode()
  911. // Desc: Funkcia sa vola rekrizivne - vytvara nody
  912. //------------------------------------------------------------------
  913. void OCTREE::CreateNode(OCTNODE *N)
  914. {
  915.  
  916.     int i;
  917.  
  918.     //vypocita stred
  919.     N->Centre.X = (N->Min.X + N->Max.X) / 2.0f;
  920.     N->Centre.Y = (N->Min.Y + N->Max.Y) / 2.0f;
  921.     N->Centre.Z = (N->Min.Z + N->Max.Z) / 2.0f;
  922.  
  923.     //vypocita polomer
  924.     N->Polomer = CalcDistance(N->Centre,N->Min);
  925.  
  926.     //zresetuje vlastnosti
  927.     N->NumFaces = 0;
  928.  
  929.     //zisti face ktore lezia v node
  930.     int *Index = NULL;
  931.     Index = new int[NumFaces];
  932.  
  933.     for (i=0;i<NumFaces;i++)
  934.     {
  935.         if (ColliseNodeFace(N,Face[i]) == true)
  936.         {
  937.             Index[N->NumFaces] = i;
  938.             N->NumFaces++;
  939.         }
  940.     }
  941.  
  942.     //skopiruje a vytvori pole
  943.     N->FaceList = new int [N->NumFaces];
  944.     for (i=0;i<N->NumFaces;i++)
  945.     {
  946.         N->FaceList[i] = Index[i];
  947.     }
  948.  
  949.     //vymaze pomocne pole
  950.     if (Index != NULL)
  951.         delete [] Index;
  952.  
  953.     //zisti ci ma pokracovat vo vytvarani dalsej nody
  954.     if(((N->Centre.X - N->Min.X) < MinNodeSize) || (N->NumFaces == 0  ))
  955.     {
  956.         N->EndNode = true;
  957.  
  958.         if (N->NumFaces>0)
  959.             NumEndNodes++;
  960.  
  961.         return ;
  962.     }
  963.  
  964.     //vymaze pole nody pretoze nieje konecna
  965.     if (N->FaceList != NULL)
  966.         delete [] N->FaceList;
  967.  
  968.     ///////////////////////
  969.     //vytvori dalsie nody//
  970.     ///////////////////////
  971.     N->EndNode = false;
  972.  
  973.     N->Node[0] = new OCTNODE;
  974.     N->Node[1] = new OCTNODE;
  975.     N->Node[2] = new OCTNODE;
  976.     N->Node[3] = new OCTNODE;
  977.     N->Node[4] = new OCTNODE;
  978.     N->Node[5] = new OCTNODE;
  979.     N->Node[6] = new OCTNODE;
  980.     N->Node[7] = new OCTNODE;
  981.  
  982.     ///
  983.     ///Dole
  984.     ///
  985.  
  986.     //0
  987.     N->Node[0]->Min.X = N->Min.X;
  988.     N->Node[0]->Min.Y = N->Min.Y;
  989.     N->Node[0]->Min.Z = N->Centre.Z;
  990.     N->Node[0]->Max.X = N->Centre.X;
  991.     N->Node[0]->Max.Y = N->Centre.Y;
  992.     N->Node[0]->Max.Z = N->Max.Z;
  993.     CreateNode(N->Node[0]);
  994.  
  995.     //1
  996.     N->Node[1]->Min.X = N->Centre.X;
  997.     N->Node[1]->Min.Y = N->Min.Y;
  998.     N->Node[1]->Min.Z = N->Centre.Z;
  999.     N->Node[1]->Max.X = N->Max.X;
  1000.     N->Node[1]->Max.Y = N->Centre.Y;
  1001.     N->Node[1]->Max.Z = N->Max.Z;
  1002.     CreateNode(N->Node[1]);
  1003.  
  1004.     //2
  1005.     N->Node[2]->Min.X = N->Min.X;
  1006.     N->Node[2]->Min.Y = N->Min.Y;
  1007.     N->Node[2]->Min.Z = N->Min.Z;
  1008.     N->Node[2]->Max.X = N->Centre.X;
  1009.     N->Node[2]->Max.Y = N->Centre.Y;
  1010.     N->Node[2]->Max.Z = N->Centre.Z;
  1011.     CreateNode(N->Node[2]);
  1012.  
  1013.     //3
  1014.     N->Node[3]->Min.X = N->Centre.X;
  1015.     N->Node[3]->Min.Y = N->Min.Y;
  1016.     N->Node[3]->Min.Z = N->Min.Z;
  1017.     N->Node[3]->Max.X = N->Max.X;
  1018.     N->Node[3]->Max.Y = N->Centre.Y;
  1019.     N->Node[3]->Max.Z = N->Centre.Z;
  1020.     CreateNode(N->Node[3]);
  1021.  
  1022.     ///
  1023.     ///Hore
  1024.     ///
  1025.  
  1026.     //4
  1027.     N->Node[4]->Min.X = N->Min.X;
  1028.     N->Node[4]->Min.Y = N->Centre.Y;
  1029.     N->Node[4]->Min.Z = N->Centre.Z;
  1030.     N->Node[4]->Max.X = N->Centre.X;
  1031.     N->Node[4]->Max.Y = N->Max.Y;
  1032.     N->Node[4]->Max.Z = N->Max.Z;
  1033.     CreateNode(N->Node[4]);
  1034.  
  1035.     //5
  1036.     N->Node[5]->Min.X = N->Centre.X;
  1037.     N->Node[5]->Min.Y = N->Centre.Y;
  1038.     N->Node[5]->Min.Z = N->Centre.Z;
  1039.     N->Node[5]->Max.X = N->Max.X;
  1040.     N->Node[5]->Max.Y = N->Max.Y;
  1041.     N->Node[5]->Max.Z = N->Max.Z;
  1042.     CreateNode(N->Node[5]);
  1043.  
  1044.     //6
  1045.     N->Node[6]->Min.X = N->Min.X;
  1046.     N->Node[6]->Min.Y = N->Centre.Y;
  1047.     N->Node[6]->Min.Z = N->Min.Z;
  1048.     N->Node[6]->Max.X = N->Centre.X;
  1049.     N->Node[6]->Max.Y = N->Max.Y;
  1050.     N->Node[6]->Max.Z = N->Centre.Z;
  1051.     CreateNode(N->Node[6]);
  1052.  
  1053.     //7
  1054.     N->Node[7]->Min.X = N->Centre.X;
  1055.     N->Node[7]->Min.Y = N->Centre.Y;
  1056.     N->Node[7]->Min.Z = N->Min.Z;
  1057.     N->Node[7]->Max.X = N->Max.X;
  1058.     N->Node[7]->Max.Y = N->Max.Y;
  1059.     N->Node[7]->Max.Z = N->Centre.Z;
  1060.     CreateNode(N->Node[7]);
  1061.     
  1062.  
  1063.  
  1064. }
  1065.  
  1066. //------------------------------------------------------------------
  1067. // Name: ColliseNodeLine()
  1068. // Desc: Zisti koliziu usecky a nody
  1069. //------------------------------------------------------------------
  1070. bool OCTREE::ColliseNodeLine(OCTNODE *N,VECTOR3D P1,VECTOR3D P2)
  1071. {
  1072.     if (CollisionBoxEdge(P1,P2,N->Min,N->Max) == true)
  1073.         return true;
  1074.     else
  1075.         return false;
  1076.  
  1077. }
  1078.  
  1079.  
  1080. //------------------------------------------------------------------
  1081. // Name: ColliseNodeFace()
  1082. // Desc: Zisti koliziu medzi Face a node - zisti ci sa face nachazda v node
  1083. //------------------------------------------------------------------
  1084. bool OCTREE::ColliseNodeFace(OCTNODE *N,OCTFACE F)
  1085. {
  1086.     if (ColliseNodeLine(N,F.P[0],F.P[1]) == true)
  1087.         return true;
  1088.     if (ColliseNodeLine(N,F.P[1],F.P[2]) == true)
  1089.         return true;
  1090.     if (ColliseNodeLine(N,F.P[0],F.P[2]) == true)
  1091.         return true;
  1092.  
  1093.  
  1094.     return false;
  1095.  
  1096. }
  1097.  
  1098. //------------------------------------------------------------------
  1099. // Name: RenderDebugNode()
  1100. // Desc: graficky zobrazi octree
  1101. //------------------------------------------------------------------
  1102. void OCTREE::RenderDebugNode(OCTNODE *N)
  1103. {
  1104.     
  1105.     if (N->EndNode == true)
  1106.     {
  1107.         //if (Camera.FrustrumSphere(N->Centre ,N->Polomer ) == false)
  1108.         //    return;
  1109.  
  1110.         if (N->NumFaces > 0)
  1111.         {
  1112.             DebugDrawBox(N->Min,N->Max);
  1113.         }
  1114.     }
  1115.  
  1116.     if (N->EndNode == false)
  1117.     {
  1118.         RenderDebugNode(N->Node[0]);
  1119.         RenderDebugNode(N->Node[1]);
  1120.         RenderDebugNode(N->Node[2]);
  1121.         RenderDebugNode(N->Node[3]);
  1122.         RenderDebugNode(N->Node[4]);
  1123.         RenderDebugNode(N->Node[5]);
  1124.         RenderDebugNode(N->Node[6]);
  1125.         RenderDebugNode(N->Node[7]);
  1126.     }
  1127.  
  1128. }
  1129.  
  1130. //------------------------------------------------------------------
  1131. // Name: Optimalize()
  1132. // Desc: Vyberie tie face ktore su vidie¥
  1133. //------------------------------------------------------------------
  1134. void OCTREE::Optimalize()
  1135. {
  1136.  
  1137.     //oznaci vsetky face ako neviditelne
  1138.     for (int i=0;i<NumFaces;i++)
  1139.     {
  1140.         Face[i].Visible = false;
  1141.     } 
  1142.  
  1143.     //frustrum culling
  1144.     FrustrumNode(Node);
  1145.  
  1146.     //backface culing
  1147.     BackFaceCulling();
  1148.  
  1149. }
  1150.  
  1151. //------------------------------------------------------------------
  1152. // Name: FrustumNode()
  1153. // Desc: Frustrum culling
  1154. //------------------------------------------------------------------
  1155. void OCTREE::FrustrumNode(OCTNODE *N)
  1156. {
  1157.     
  1158.     //ako node neobsahuje ziadny face vyhod
  1159.     if (N->NumFaces == 0)
  1160.         return;
  1161.  
  1162.     //ak nieje v dohlade
  1163.     if (Camera.FrustrumSphere(N->Centre,N->Polomer) == false)
  1164.         return;
  1165.  
  1166.     //
  1167.     if (N->EndNode == true)
  1168.     {
  1169. //        if (Camera.FrustrumSphere(N->Centre,N->Polomer) == false)
  1170. //        return;
  1171.  
  1172.         for (int i=0;i<N->NumFaces;i++)
  1173.         {
  1174.             Face[N->FaceList[i]].Visible = true;
  1175.         }
  1176.     }
  1177.     else
  1178.     {
  1179.         FrustrumNode(N->Node[0]);
  1180.         FrustrumNode(N->Node[1]);
  1181.         FrustrumNode(N->Node[2]);
  1182.         FrustrumNode(N->Node[3]);
  1183.         FrustrumNode(N->Node[4]);
  1184.         FrustrumNode(N->Node[5]);
  1185.         FrustrumNode(N->Node[6]);
  1186.         FrustrumNode(N->Node[7]);
  1187.     }
  1188.  
  1189. }
  1190.  
  1191. //------------------------------------------------------------------
  1192. // Name: ColliseFace()
  1193. // Desc: Zisti koliziu s facom
  1194. //------------------------------------------------------------------
  1195. bool OCTREE::ColliseFace(OCTFACE F, VECTOR3D P1, VECTOR3D P2)
  1196. {
  1197.     VECTOR3D Inter;
  1198.     float U,U1,U2,U3;
  1199.  
  1200.     if (CalcPriesEdge(&Inter,F.Plane,P1,P2) == true)
  1201.     {
  1202.         U1 = CalcAngleCentre(Inter,F.P[0],
  1203.                                    F.P[1]);
  1204.         U2 = CalcAngleCentre(Inter,F.P[1],
  1205.                                    F.P[2]);
  1206.         U3 = CalcAngleCentre(Inter,F.P[2],
  1207.                                    F.P[0]);
  1208.  
  1209.         U = U1+U2+U3;
  1210.  
  1211.         if (U > 6.2f && U < 6.35f)
  1212.         {
  1213.             ColliseStatus = true;
  1214.             IntPos = Inter;
  1215.             IntNormal = F.Plane.Normal;
  1216.             IntMaterialType = Group[F.Group ].MaterialType ;
  1217.             IntBlendType = Group[F.Group ].BlendType ;
  1218.             IntGroupType = Group[F.Group ].GroupType ;
  1219.  
  1220.             return true;
  1221.         }
  1222.         else
  1223.         {
  1224.             return false;
  1225.         }
  1226.     }
  1227.     else
  1228.     {
  1229.         return false;
  1230.     }
  1231. }
  1232.  
  1233. //------------------------------------------------------------------
  1234. // Name: ColliseFaceDistance()
  1235. // Desc: Zisti koliziu s facom vyberie najblizsi priesecnik
  1236. //------------------------------------------------------------------
  1237. bool OCTREE::ColliseFaceDistance(OCTFACE F, VECTOR3D P1, VECTOR3D P2)
  1238. {
  1239.     VECTOR3D Inter;
  1240.     float U,U1,U2,U3;
  1241.  
  1242.     if (CalcPriesEdge(&Inter,F.Plane,P1,P2) == true)
  1243.     {
  1244.         U1 = CalcAngleCentre(Inter,F.P[0],
  1245.                                    F.P[1]);
  1246.         U2 = CalcAngleCentre(Inter,F.P[1],
  1247.                                    F.P[2]);
  1248.         U3 = CalcAngleCentre(Inter,F.P[2],
  1249.                                    F.P[0]);
  1250.  
  1251.         U = U1+U2+U3;
  1252.  
  1253.         if (U > 6.2f && U < 6.35f)
  1254.         {
  1255.             if (ColliseStatus ==false)
  1256.             {
  1257.                 ColliseStatus = true;
  1258.                 IntPos = Inter;
  1259.                 IntNormal = F.Plane.Normal;
  1260.                 IntMaterialType = Group[F.Group ].MaterialType ;
  1261.                 IntBlendType = Group[F.Group ].BlendType ;
  1262.                 IntGroupType = Group[F.Group ].GroupType ;
  1263.             }
  1264.             else
  1265.             {
  1266.                 float Dis1 = CalcDistance(P1,Inter);
  1267.                 float Dis2 = CalcDistance(P1,IntPos);
  1268.  
  1269.                 if(Dis1 < Dis2)
  1270.                 {
  1271.                     IntPos = Inter;
  1272.                     IntNormal = F.Plane.Normal;
  1273.                     IntMaterialType = Group[F.Group ].MaterialType ;
  1274.                     IntBlendType = Group[F.Group ].BlendType ;
  1275.                     IntGroupType = Group[F.Group ].GroupType ;
  1276.         
  1277.                 }
  1278.  
  1279.             }
  1280.  
  1281.             return true;
  1282.         }
  1283.         else
  1284.         {
  1285.             return false;
  1286.         }
  1287.     }
  1288.     else
  1289.     {
  1290.         return false;
  1291.     }
  1292. }
  1293.  
  1294. //------------------------------------------------------------------
  1295. // Name: ColliseNode()
  1296. // Desc: rekruziva na koliziu
  1297. //------------------------------------------------------------------
  1298. void OCTREE::ColliseNode(OCTNODE *N, VECTOR3D P1, VECTOR3D P2)
  1299. {
  1300.     int GroupIndex;
  1301.     int FaceIndex;
  1302.  
  1303.     //
  1304.     //ak uz je kolizia dalej koliziu neprevadzat
  1305.     //
  1306.     if (ColliseStatus == true)
  1307.         return;
  1308.  
  1309.     //
  1310.     //ak luc prechadzat nodov
  1311.     //
  1312.     if (ColliseNodeLine(N,P1,P2) == true)
  1313.     {
  1314.         //ak to je konecna noda
  1315.         if (N->EndNode == true)
  1316.         {
  1317.             for (int i=0;i<N->NumFaces;i++)
  1318.             {
  1319.                 //zisti indexi
  1320.                 FaceIndex = N->FaceList[i];
  1321.                 GroupIndex = Face[FaceIndex].Group ;
  1322.  
  1323.                 //ak je zapnuta kolizia skupiny
  1324.                 if (!(Group[GroupIndex].CollisionType == 1 && Mode == 1))
  1325.                 {
  1326.                     if (ColliseFace(Face[FaceIndex],P1,P2) == true)
  1327.                         break;
  1328.                 }
  1329.             }
  1330.         }
  1331.         //
  1332.         //inak otestuj vsetky podnody
  1333.         //
  1334.         else
  1335.         {
  1336.             ColliseNode(N->Node[0],P1,P2);
  1337.             ColliseNode(N->Node[1],P1,P2);
  1338.             ColliseNode(N->Node[2],P1,P2);
  1339.             ColliseNode(N->Node[3],P1,P2);
  1340.             ColliseNode(N->Node[4],P1,P2);
  1341.             ColliseNode(N->Node[5],P1,P2);
  1342.             ColliseNode(N->Node[6],P1,P2);
  1343.             ColliseNode(N->Node[7],P1,P2);
  1344.         }
  1345.     }
  1346.     
  1347.  
  1348. }
  1349.  
  1350.  
  1351. //------------------------------------------------------------------
  1352. // Name: ColliseNodeDistance()
  1353. // Desc: otestuje vsetky polygony a vybere najblizsi priesecnik k bodu P1
  1354. //------------------------------------------------------------------
  1355. void OCTREE::ColliseNodeDistance(OCTNODE *N, VECTOR3D P1, VECTOR3D P2)
  1356. {
  1357.     int GroupIndex;
  1358.     int FaceIndex;
  1359.  
  1360.     //
  1361.     //ak luc prechadzat nodov
  1362.     //
  1363.     if (ColliseNodeLine(N,P1,P2) == true)
  1364.     {
  1365.         //ak to je konecna noda
  1366.         if (N->EndNode == true)
  1367.         {
  1368.             for (int i=0;i<N->NumFaces;i++)
  1369.             {
  1370.                 //zisti indexi
  1371.                 FaceIndex = N->FaceList[i];
  1372.                 GroupIndex = Face[FaceIndex].Group ;
  1373.  
  1374.                 //ak je zapnuta kolizia skupiny
  1375.                 if (!(Group[GroupIndex].CollisionType == 1 && Mode == 1))
  1376.                 {
  1377.                     ColliseFaceDistance(Face[FaceIndex],P1,P2);
  1378.                 }
  1379.             }
  1380.         }
  1381.         //
  1382.         //inak otestuj vsetky podnody
  1383.         //
  1384.         else
  1385.         {
  1386.             ColliseNodeDistance(N->Node[0],P1,P2);
  1387.             ColliseNodeDistance(N->Node[1],P1,P2);
  1388.             ColliseNodeDistance(N->Node[2],P1,P2);
  1389.             ColliseNodeDistance(N->Node[3],P1,P2);
  1390.             ColliseNodeDistance(N->Node[4],P1,P2);
  1391.             ColliseNodeDistance(N->Node[5],P1,P2);
  1392.             ColliseNodeDistance(N->Node[6],P1,P2);
  1393.             ColliseNodeDistance(N->Node[7],P1,P2);
  1394.         }
  1395.     }
  1396.     
  1397.  
  1398. }
  1399. //------------------------------------------------------------------
  1400. // Name: Collise()
  1401. // Desc: funkcia testuje koliziu s terenom
  1402. //------------------------------------------------------------------
  1403. bool OCTREE::Collise(VECTOR3D P1,VECTOR3D P2)
  1404. {
  1405.     
  1406.     //zresetuje
  1407.     ColliseStatus = false;
  1408.  
  1409.     ColliseNode(Node,P1,P2);
  1410.  
  1411.     return ColliseStatus;
  1412.  
  1413. }
  1414.  
  1415. //------------------------------------------------------------------
  1416. // Name: ColliseDistance()
  1417. // Desc: funkcia testuje koliziu s terenom vyberie najblizsi priesecnik
  1418. //------------------------------------------------------------------
  1419. bool OCTREE::ColliseDistance(VECTOR3D P1,VECTOR3D P2)
  1420. {
  1421.     //zresetuje
  1422.     ColliseStatus = false;
  1423.  
  1424.     ColliseNodeDistance(Node,P1,P2);
  1425.  
  1426.     return ColliseStatus;
  1427.  
  1428. }
  1429. //------------------------------------------------------------------
  1430. // Name: SaveScene()
  1431. // Desc: ulozi optimalizovanu scenu
  1432. //------------------------------------------------------------------
  1433. void OCTREE::SaveScene(char *FileName)
  1434. {
  1435.     
  1436.     //otvori suber pre bynarny zapis
  1437.     FileScn = fopen(FileName,"wb");
  1438.  
  1439.     //zapise pocet facov
  1440.     int NumF = NumFaces;
  1441.     fwrite(&NumF,sizeof(int),1,FileScn);
  1442.  
  1443.     //zapise faces
  1444.     fwrite(Face,sizeof(OCTFACE),NumF,FileScn);
  1445.  
  1446.     //zatvor subor
  1447.     fclose(FileScn);
  1448.  
  1449.  
  1450. }
  1451.  
  1452.  
  1453. //------------------------------------------------------------------
  1454. // Name: LoadScene()
  1455. // Desc: Otvori optimalizovanu scenu
  1456. //------------------------------------------------------------------
  1457. void OCTREE::LoadScene(char *FileNameGeo,char *FileNameScn)
  1458. {
  1459.     
  1460.     char cBuf[80];
  1461.     int i;
  1462.     int NumF;
  1463.  
  1464.     //Log
  1465.     LogPrint("Vytvaram OCTree");
  1466.     sprintf(cBuf," Subor Geo: %s",FileNameGeo);
  1467.     LogPrint(cBuf);
  1468.     sprintf(cBuf," Subor Scn: %s",FileNameScn);
  1469.     LogPrint(cBuf);
  1470.     
  1471.  
  1472.     ///////////////////
  1473.     //otvor subor GEO//
  1474.     ///////////////////
  1475.     FileGeo = fopen(FileNameGeo,"r");
  1476.  
  1477.     if (FileGeo == NULL)
  1478.         LogPrint(" Subor GEO sa nepodarilo otvorit");
  1479.  
  1480.     ///////////////////
  1481.     //otvor subor SCN//
  1482.     ///////////////////
  1483.     FileScn = fopen(FileNameScn,"rb");
  1484.  
  1485.     if (FileScn == NULL)
  1486.         LogPrint(" Subor SCN sa nepodarilo otvorit");
  1487.  
  1488.  
  1489.     ///////////////
  1490.     //hlavicka   //
  1491.     ///////////////
  1492.     fscanf(FileGeo,"%s %d",cBuf,&MinNodeSize);
  1493.     fscanf(FileGeo,"%s %d",cBuf,&NumGroups);
  1494.     fscanf(FileGeo,"%s %d",cBuf,&NumFaces);
  1495.  
  1496.     sprintf(cBuf," MinPolygonsInNode: %d",MinNodeSize);
  1497.     LogPrint(cBuf);
  1498.     sprintf(cBuf," NumGroups: %d",NumGroups);
  1499.     LogPrint(cBuf);
  1500.     sprintf(cBuf," NumFaces: %d",NumFaces);
  1501.     LogPrint(cBuf);
  1502.     
  1503.  
  1504.     ///////////////
  1505.     //group      //
  1506.     ///////////////
  1507.  
  1508.     Group = new OCTGROUP[NumGroups];
  1509.     for (i=0;i<NumGroups;i++)
  1510.     {
  1511.         ReadGroup();
  1512.     }
  1513.  
  1514.     ///////////////
  1515.     //faces      //
  1516.     ///////////////
  1517.     Face = new OCTFACE[NumFaces];
  1518.     fread(&NumF,sizeof(int),1,FileScn);
  1519.     for(i = 0;i<NumF;i++)
  1520.         fread(&Face[i],sizeof(OCTFACE),1,FileScn);
  1521.  
  1522.  
  1523.     /////////////////
  1524.     //Vertex Buffer//
  1525.     /////////////////
  1526.     CreateVertexBuffer();
  1527.  
  1528.     ////////////////
  1529.     //zatvor subor//
  1530.     ////////////////
  1531.     fclose(FileGeo);
  1532.     fclose(FileScn);
  1533.  
  1534.     ///////////
  1535.     //OCTree //
  1536.     ///////////
  1537.     //CreateOctTree();
  1538.  
  1539. }
  1540.  
  1541. //------------------------------------------------------------------
  1542. // Name: BackFaceCulling()
  1543. // Desc: odstrani zadnΘ hrany
  1544. //------------------------------------------------------------------
  1545. void OCTREE::BackFaceCulling()
  1546. {
  1547.  
  1548.     for (int i=0;i<NumFaces;i++)
  1549.     {
  1550.         if (Face[i].Visible == true)
  1551.         {
  1552.             if (PointPlane(Face[i].Plane,Camera.Pos) > 0.0f)
  1553.                 Face[i].Visible = false;
  1554.         }
  1555.     }
  1556.  
  1557. }
  1558.  
  1559. //------------------------------------------------------------------
  1560. // Name: SetTexture()
  1561. // Desc: nastavi externu texturu do skupiny
  1562. //------------------------------------------------------------------
  1563. void OCTREE::SetTexture(int ToGroup,int ToFrame,LPDIRECT3DTEXTURE9 Tex)
  1564. {
  1565.     Group[ToGroup].g_pTexture[ToFrame] = Tex;
  1566. }
  1567.  
  1568.  
  1569. //------------------------------------------------------------------
  1570. // Name: LoadOctTree()
  1571. // Desc: nacita octree storm
  1572. //------------------------------------------------------------------
  1573. void OCTREE::LoadOctTree(char *FileName)
  1574. {
  1575.  
  1576.  
  1577.     //subor
  1578.     FileOct = fopen(FileName,"rb");
  1579.  
  1580.     //zachytavanie chyb
  1581.     if (FileOct == NULL)
  1582.     {
  1583.         char cBuf[80];
  1584.         sprintf(cBuf,"Nemozem najst subor %s",FileName);
  1585.     }
  1586.  
  1587.     //loadne strom
  1588.     Node = new OCTNODE;
  1589.     LoadNode(Node);
  1590.  
  1591.     //zatvor
  1592.     fclose(FileOct);
  1593.     FileOct = NULL;
  1594.  
  1595. }
  1596.  
  1597. //------------------------------------------------------------------
  1598. // Name: SaveOctTree()
  1599. // Desc: ulozi octree stom
  1600. //------------------------------------------------------------------
  1601. void OCTREE::SaveOctTree(char *FileName)
  1602. {
  1603.     //subor
  1604.     FileOct = fopen(FileName,"wb");
  1605.  
  1606.     //ulozi strom
  1607.     SaveNode(Node);
  1608.  
  1609.     //zatvor
  1610.     fclose(FileOct);
  1611.     FileOct = NULL;
  1612.     
  1613.  
  1614. }
  1615.  
  1616. //------------------------------------------------------------------
  1617. // Name: SaveNone()
  1618. // Desc: ulozi nodu octtree
  1619. //------------------------------------------------------------------
  1620. void OCTREE::SaveNode(OCTNODE *N)
  1621. {
  1622.  
  1623.     OCTRNODE RNode;
  1624.  
  1625.     //rnode
  1626.     RNode.Centre = N->Centre;
  1627.     RNode.EndNode = N->EndNode ;
  1628.     RNode.Max = N->Max;
  1629.     RNode.Min = N->Min;
  1630.     RNode.NumFaces = N->NumFaces;
  1631.     RNode.Polomer = N->Polomer;
  1632.  
  1633.     //zapis - node
  1634.     fwrite(&RNode,sizeof(OCTRNODE),1,FileOct);
  1635.  
  1636.     //zapis - facelist ak je konecna
  1637.     if (RNode.EndNode == true)
  1638.         fwrite(N->FaceList,sizeof(int),RNode.NumFaces,FileOct);
  1639.  
  1640.     //ak je konecna node tak vyhod
  1641.     if (RNode.EndNode == true)
  1642.         return;
  1643.  
  1644.     //inak uloz sub nody
  1645.     SaveNode(N->Node[0]);
  1646.     SaveNode(N->Node[1]);
  1647.     SaveNode(N->Node[2]);
  1648.     SaveNode(N->Node[3]);
  1649.     SaveNode(N->Node[4]);
  1650.     SaveNode(N->Node[5]);
  1651.     SaveNode(N->Node[6]);
  1652.     SaveNode(N->Node[7]);
  1653.  
  1654. }
  1655.  
  1656. //------------------------------------------------------------------
  1657. // Name: LoadNone()
  1658. // Desc: nacita nodu octree
  1659. //------------------------------------------------------------------
  1660. void OCTREE::LoadNode(OCTNODE *N)
  1661. {
  1662.  
  1663.     
  1664.     OCTRNODE RNode;
  1665.  
  1666.     //precita - node
  1667.     fread(&RNode,sizeof(OCTRNODE),1,FileOct);
  1668.  
  1669.     //precita - facelist ak je konecna
  1670.     if (RNode.EndNode == true)
  1671.     { 
  1672.         N->FaceList = new int[RNode.NumFaces];
  1673.         fread(N->FaceList,sizeof(int),RNode.NumFaces,FileOct);
  1674.     }
  1675.  
  1676.     //rnode
  1677.     N->Centre = RNode.Centre;
  1678.     N->EndNode = RNode.EndNode ;
  1679.     N->Max = RNode.Max;
  1680.     N->Min = RNode.Min;
  1681.     N->NumFaces = RNode.NumFaces;
  1682.     N->Polomer = RNode.Polomer;
  1683.  
  1684.     //ak je konecna node tak vyhod
  1685.     if (RNode.EndNode == true)
  1686.         return;
  1687.  
  1688.     //vytvor sub nody
  1689.     N->Node[0] = new OCTNODE;
  1690.     N->Node[1] = new OCTNODE;
  1691.     N->Node[2] = new OCTNODE;
  1692.     N->Node[3] = new OCTNODE;
  1693.     N->Node[4] = new OCTNODE;
  1694.     N->Node[5] = new OCTNODE;
  1695.     N->Node[6] = new OCTNODE;
  1696.     N->Node[7] = new OCTNODE;
  1697.  
  1698.     //uloz sub nody
  1699.     LoadNode(N->Node[0]);
  1700.     LoadNode(N->Node[1]);
  1701.     LoadNode(N->Node[2]);
  1702.     LoadNode(N->Node[3]);
  1703.     LoadNode(N->Node[4]);
  1704.     LoadNode(N->Node[5]);
  1705.     LoadNode(N->Node[6]);
  1706.     LoadNode(N->Node[7]);
  1707.  
  1708. }
  1709.